

#ifndef LWR_H
#define	LWR_H

#include <selforg/matrix.h>
#include <cmath>
using namespace matrix;

/** 
 * File:   lwr.h
 * 
 * Class that implements locally weighted regression as predictor.
 * The regression coefficients are updated in batch mode based on the  least squares estimator.
 * As presented in Chapter 3.2.2 of the thesis.
 *
 * 
 * @author:  Athanasios Polydoros
 * @version: 1.0
 * Created on 09 July 2013, 19:28
 */

class LWR {
public:
     /**
     * Class constructor that initialise the members of class. Has to be called
     * in the controller's init method.
     * 
     * @param num_Sensors The number of robot sensors, used as network's outputs
     * @param num_Motors  The number of motors, used as inputs
     */
    LWR(int numSensors, int numMotors);
    
    /**
     * Class destructor
     */
    virtual ~LWR();
    
      /**
     * Set the current inputs.
     * 
      * This method is called within 
     * controler's method : learn() before the method @see predict()
      * 
     * @param motors The values of robot's motors   
     */
    void setState(Matrix motors);
    
    /**
     * Sets the desired output. This method is called within 
     * controler's method : learn() before the method @see predict()
     * 
     * @param sensor the robot's desired sensory values 
     */
    void setDesiredOut(Matrix sensors);
    
      /**
    *  Predicts the future sensor values based on the current motor commands (inputs).
     * 
     * 
     * @return Matrix that contains the predicted sensory values. 
    */
    Matrix predict();
    
     /**
      * Calculate the jacobian matrix.
      * In the case of regression, it is simply the matrix of regression coefficients
     * without the bias weight.
      * 
      * @param the input nodes values 
      * @return MxM Jacobian matrix
      */
    Matrix getModelMatrix();
private:
    /**
     * Adds to memory an input and its corresponding output  
     * @param instance   The input
     * @param desiredOut  he actual output
     */
    void addToMemory(Matrix instance,Matrix desiredOut);
    /**
     * Calculates the weights of each memorized input-output according to the current
     * input (query point) based on the eucidean distance and Gaussian Kernel
     */
    void findWeights();
    
    /**
     * Applies the weights at the data in the memory 
     */
    void weightData();
    /**
     * Calculates the regression coefficients based on the Least Square formula
     */
    void findRegressionCoefficieents();
    /**
     * Method used for finding the euclidian distance between two vectors 
     * @param vector1 
     * @param vector2
     * @return  The Euclidean distance between the input vectors
     */
    double euclideanDistance(Matrix vector1,Matrix vector2);
    
    int inputNum;
    int outputNum;
    
    Matrix weights;
    Matrix regressionCoeff;
    Matrix inputHistory;
    Matrix outputHistory;
    Matrix currentInput; /**< Query point*/
    Matrix desiredOutput;
    Matrix weightedInputs; /**<History of inputs after weighting*/ 
    Matrix weightedOutputs; /**<History of outputs after weighting*/
    
    
};

#endif	/* LWR_H */

